package br.com.ifactory.tools;

/*
 * Author: Alexandro Felix
 * Date: 02/09/2011
 */


import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.ParseException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jfree.data.xy.XYSeries;
import org.jfree.ui.RefineryUtilities;

public class JrockitGcLogParser {

    public void doFile(File gcLog, String fileToBeGenerated) throws IOException, ParseException {

        File f = gcLog;
        File f1 = new File(fileToBeGenerated);

        FileReader fr = null;

        fr = new FileReader(f);//reads file to be parsed
        BufferedReader br = new BufferedReader(fr);
        FileWriter fw = new FileWriter(f1);//file to be created

        //header
        fw.write("Hora\t\t\t\"Nursery Size\"\t\t\"Heap Usage\"\t\t\"Committed Heap\"\t\t\"GC Pause(ms)\"\t\t\n");

        //goes through file line by line
        readFile(br, fr, fw);
    }

    public static void readFile(BufferedReader br, FileReader fr, FileWriter fw) throws IOException, ParseException {

        Pattern p0 = Pattern.compile("... ...  \\d [0-9][0-9]:[0-9][0-9]:[0-9][0-9] 20..");//regex to match eventTime
        Pattern p1 = Pattern.compile("[0-9]{1,7}(?=K->)");//regex to match heap usage before gc
        Pattern p2 = Pattern.compile("(?<=K->)[0-9]{1,7}");//regex to match heap usage after gc
        Pattern p3 = Pattern.compile("(?<=nursery size: )[0-9]{1,7}");//regex to match nursery size
        Pattern p4 = Pattern.compile("[0-9]{1,7}(?=.[0-9][0-9][0-9] ms)");//regex to match gc pause time
        Pattern p5 = Pattern.compile("[0-9]{1,7}(?=K.,)");//regex to match commited heap
        Pattern p6 = Pattern.compile("[0-9]{1,7}\\.[0-9]{3}(?=-)");//event start time since jvm was started
        Pattern p7 = Pattern.compile("[0-9]{1,7}\\.[0-9]{3}(?=: )");//event end time since jvm was started
        
        Matcher m0 = null;
        Matcher m1 = null;
        Matcher m2 = null;
        Matcher m3 = null;
        Matcher m4 = null;
        Matcher m5 = null;
        Matcher m6 = null;
        Matcher m7 = null;

        String eventTime = null, eventStartTime = null, eventEndTime = null, nurserySize = null,
                heapUsageBeforeGC = "", heapUsageAfterGC = "", commitedHeap = null, gcPause = null;

        String sLine = null;

        //initializes Chart
        TimeChart chart = null;

        XYSeries s0 = new XYSeries("Heap Usage");
        XYSeries s1 = new XYSeries("GC Pause");

        try {
            chart = new TimeChart("Heap Graph");
        } catch (ParseException ex) {
            Logger.getLogger(HomeFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
        chart.pack();
        RefineryUtilities.centerFrameOnScreen(chart);
        chart.setVisible(true);

        try {

            while ((sLine = br.readLine()) != null) {

                //applying the regexes
                m0 = p0.matcher(sLine);
                m1 = p1.matcher(sLine);
                m2 = p2.matcher(sLine);
                m3 = p3.matcher(sLine);
                m4 = p4.matcher(sLine);
                m5 = p5.matcher(sLine);
                m6 = p6.matcher(sLine);
                m7 = p7.matcher(sLine);

                if (m0.find()) {
                    eventTime = m0.group();
                }

                if (m3.find()) {
                    nurserySize = m3.group();
                }

                if (m1.find()) {
                    heapUsageBeforeGC = m1.group();
                }

                if (m2.find()) {
                    heapUsageAfterGC = m2.group();
                }

                if (m5.find()) {
                    commitedHeap = m5.group();
                }

                if (m4.find()) {
                    gcPause = m4.group();
                }
                
                if (m6.find()){
                    eventStartTime = m6.group();
                }
                
                if (m7.find()){
                    eventEndTime = m7.group();
                }

                int iGCPause = 0;
                if (!heapUsageBeforeGC.isEmpty()) {
                    if(eventStartTime == null){
                        eventStartTime = eventEndTime;
                    }
                    fw.write("\"" + eventStartTime + "\"" + "\t\t" + nurserySize + "\t\t" + heapUsageBeforeGC + "\t\t"
                            + commitedHeap + "\t\t\t" + gcPause + "\n");
                    
                    int iCommitedHeap = Integer.parseInt(commitedHeap);
                    int heapUsage = Integer.parseInt(heapUsageBeforeGC) / 1000000;
                    iGCPause = Integer.parseInt(gcPause);
                    double dEventStartTime = Double.parseDouble(eventStartTime);
                    eventStartTime = null;
                    long lEventStartTime = (long) dEventStartTime;
                    chart.makeChart(lEventStartTime, heapUsage,iGCPause, iCommitedHeap, s0, s1);
                    
                    

                }

                if (!heapUsageAfterGC.isEmpty()) {
                    
                    fw.write("\"" + eventEndTime + "\"" + "\t\t" + nurserySize + "\t\t" + heapUsageAfterGC + "\t\t"
                            + commitedHeap + "\t\t\t" + gcPause + "\n");
                                      
                    int iCommitedHeap = Integer.parseInt(commitedHeap);
                    int heapUsage = Integer.parseInt(heapUsageAfterGC) / 1000000;
                    double dEventEndTime = Double.parseDouble(eventEndTime);
                    eventEndTime = null;
                    long lEventEndTime = (long) dEventEndTime;
                    chart.makeChart(lEventEndTime, heapUsage, iGCPause, iCommitedHeap, s0, s1);
               }

                
            }
        } catch (IOException ex) {
            Logger.getLogger(JrockitGcLogParser.class.getName()).log(Level.SEVERE, null, ex);
        }
        fr.close();
        br.close();
        fw.close();
    }
}
